#include "filesystemwatcher.h"

#include "disk.h"
#include "daemon.h"

#include <iostream>
using std::cerr;
using std::cout;
using std::endl;

namespace Avd {

FileSystemWatcher::FileSystemWatcher(Daemon* daemon) throw(InotifyException) : daemon(daemon) {
	inotify = new Inotify();
}

FileSystemWatcher::~FileSystemWatcher() {
	if(inotify)
		delete inotify;
}

void FileSystemWatcher::run() {
	forever {
		try {
			inotify->WaitForEvents();

			size_t count = inotify->GetEventCount();
			while (count > 0) {
				InotifyEvent event;
				bool got_event = inotify->GetEvent(&event);

				if (got_event) {
					string maskStr;
					string filename = event.GetName();
					string watchDir = event.GetWatch()->GetPath();

					event.DumpTypes(maskStr);
					if(watchDir.size() < 30)
						cout << "[watch " << watchDir << "] ";
					cout << "event mask: \"" << maskStr << "\", ";
					cout << "filename: \"" << filename << "\"" << endl;
				}

				count--;
			}
		}
		catch (InotifyException &e) {
			cerr << "Inotify exception occured: " << e.GetMessage() << endl;
		}
		catch (exception &e) {
			cerr << "STL exception occured: " << e.what() << endl;
		}
		catch (...) {
			cerr << "unknown exception occured" << endl;
		}
	}
}

void FileSystemWatcher::add(const Folder& folder) {
	InotifyWatch watch((daemon->getDisk()->getAbsolutePath() + folder.getFullPath()).toStdString(), IN_ALL_EVENTS);
	inotify->Add(watch);
}

void FileSystemWatcher::remove(const Folder& folder) {
	InotifyWatch watch((daemon->getDisk()->getAbsolutePath() + folder.getFullPath()).toStdString(), IN_ALL_EVENTS);
	inotify->Remove(watch);
}

}

